#include <QCloseEvent>
#include <QDateTime>
#include <QDir>
#include <QMessageBox>
#include <QSqlError>

#ifdef WIN32
	#include <Windows.h>
#endif // WIN32

#include "hbot.h"
#include "profilemanager.h"
#include "sdefs.h"
#include "xmlconfig.h"

HBot::HBot(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags), Ui::HBotClass()
{
	setupUi(this);

	m_InterfaceInitialized = false;
	m_BotRunning = false;
	m_Bot = NULL;
	
	connect(actionProfile_Manager, SIGNAL(triggered()), this, SLOT(ActionProfileManager()));
	connect(actionClose_Current_Profile, SIGNAL(triggered()), this, SLOT(CloseProfile()));
	connect(actionExit, SIGNAL(triggered()), this, SLOT(ActionCloseApplication()));

#ifdef WIN32
	SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
#endif // WIN32

	// Initialize XML configuration

	m_XMLProfile = new CXMLConfig(QString(PROFILE_XML_FILEFULL));

	// Setup 'Select Current Profile' menu with list of profiles
	
	QStringList profiles = m_XMLProfile->GetProfiles();

	if (!profiles.size())
	{
		m_ActionEmptyProfileList = menuSelect_Profile->addAction(MENU_SELECT_ACTION_EMPTYPROFILELIST);
	}
	else
	{
		m_ActionEmptyProfileList = NULL;

		for (int i = 0; i < profiles.size(); ++i)
		{
			QAction *temp = menuSelect_Profile->addAction(profiles[i]);
			connect(temp, SIGNAL(triggered()), this, SLOT(ActionSelectProfile()));
		}
	}

	actionRun_Bot->setEnabled(false);
	actionStop_Bot->setEnabled(false);

	// Setup general interface

	if (!m_XMLProfile->GetDefaultProfile().isEmpty())
	{
		labelIntroduction->deleteLater();
		InitializeInterface();
		OpenProfile(m_XMLProfile->GetDefaultProfile());
	}
}

HBot::~HBot()
{
	delete m_XMLProfile;
}

void HBot::ActionCloseApplication()
{
	close();
}

bool HBot::ActionCloseDatabase(bool button)
{
	if (!button)
	{
		switch (QMessageBox::question(this, QObject::tr("Database: Unsaved changes"), QObject::tr("The database is still opened and contains unsaved changes. Would you like to save the changes before closing the profile?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel))
		{
			case QMessageBox::Yes:
				ActionSubmitChangesDatabase();
				break;

			case QMessageBox::No:
				break;

			case QMessageBox::Cancel:
				return false;
		}
	}

	delete m_DatabaseTable;
	m_DatabaseTable = NULL;
	m_DatabaseComboBox->setEnabled(false);
	m_DatabaseDisconnectButton->setEnabled(false);
	m_DatabaseSubmitButton->setEnabled(false);
	m_DatabaseConnectButton->setEnabled(true);
	m_DatabaseInsertRowButton->setEnabled(false);
	m_DatabaseDeleteRowButton->setEnabled(false);

	return true;
}

void HBot::ActionDatabaseComboBoxChanged(int index)
{
	QString table;
	
	if (index == 0)
	{
		table = "bans";
	}
	else if (index == 1)
	{
		table = "dotagames";
	}
	else if (index == 2)
	{
		table = "dotaplayers";
	}
	else if (index == 3)
	{
		table = "games";
	}
	else if (index == 4)
	{
		table = "gameplayers";
	}
	else if (index == 5)
	{
		table = "scores";
	}
	else if (index == 6)
	{
		table = "users";
	}
	else if (index == 7)
	{
		table = "w3mmdplayers";
	}
	else if (index == 8)
	{
		table = "w3mmdvars";
	}
	/*
	This last else if is only needed for SQLite.
	*/
	else if (index == 9)
	{
		table = "config";
	}

	/*
	TODO:
	This is the only way I could fix the problem. For some reason, ONLY when I
	use MySQL, the table view does not update upon switching tables, but it does
	in SQLite. So I spent quite a while trying to fix it, but this is the only
	solution I could come up with. So I need to figure out the real problem
	behind why it is not working correctly like SQLite is.
	*/

	delete m_DatabaseTable;
	m_DatabaseTable = new QSqlTableModel();

	m_DatabaseTable->setTable(table);

	if (m_DatabaseTable->lastError().type() != QSqlError::NoError)
	{
		PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Warning opening table [" + table + "] in database:" + m_DatabaseTable->lastError().text(), QString::null, true);
		m_DatabaseInsertRowButton->setEnabled(false);
		return;
	}

	m_DatabaseTable->setEditStrategy(QSqlTableModel::OnManualSubmit);
	
	if (!m_DatabaseTable->select())
	{
		PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Warning selecting table [" + table + "] in database:" + m_DatabaseTable->lastError().text(), QString::null, true);
		m_DatabaseInsertRowButton->setEnabled(false);
		return;
	}

	m_DatabaseInsertRowButton->setEnabled(true);
	m_DatabaseTableView->setModel(m_DatabaseTable);
}

void HBot::ActionDeleteRowDatabase()
{
	m_DatabaseTable->removeRow(m_DatabaseTableView->currentIndex().row());
}

void HBot::ActionInsertRowDatabase()
{
	m_DatabaseTable->insertRow(m_DatabaseTable->rowCount());
}

void HBot::ActionOpenDatabase()
{
	if (!m_BotRunning)
	{
		m_DatabaseConnectButton->setEnabled(false);
		m_DatabaseComboBox->setEnabled(true);

		m_DatabaseTable = new QSqlTableModel(this, QSqlDatabase::QSqlDatabase());
		ActionDatabaseComboBoxChanged(m_DatabaseComboBox->currentIndex());

		m_DatabaseTableView->setSelectionMode(QAbstractItemView::SingleSelection);
		m_DatabaseTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
		m_DatabaseTableView->setModel(m_DatabaseTable);

		m_DatabaseDisconnectButton->setEnabled(true);
		m_DatabaseSubmitButton->setEnabled(true);
		m_DatabaseDeleteRowButton->setEnabled(true);
	}
}

void HBot::ActionProfileManager()
{
	m_XMLProfile->Read();
	CProfileManager profileManager(this);
	profileManager.exec();
}

void HBot::ActionSelectProfile()
{
	QAction *action = (QAction *) sender();
	
	if (!m_InterfaceInitialized)
	{
		labelIntroduction->deleteLater();
		InitializeInterface();
	}

	if (!m_CurrentProfile.isEmpty())
	{
		if (!CloseProfile())
		{
			return;
		}
	}

	OpenProfile(action->text());
}

void HBot::ActionSubmitChangesDatabase()
{
	m_DatabaseTable->database().transaction();

	if (m_DatabaseTable->submitAll())
	{
		m_DatabaseTable->database().commit();
	}
	else
	{
		m_DatabaseTable->database().rollback();

		QMessageBox::warning(this, "Database Error", QObject::tr("The database has reported an error: %1").arg(m_DatabaseTable->lastError().text()));
	}
}

void HBot::closeEvent(QCloseEvent *event)
{
	if (!m_CurrentProfile.isEmpty())
	{
		if (!CloseProfile())
		{
			event->ignore();
			return;
		}
	}

	if (m_InterfaceInitialized)
	{
		delete m_HBotInterface;
	}

	event->accept();
}

void HBot::CreateProfileDirectory(const QString &profile)
{
	QDir dir(QDir::current());
	dir.mkpath("Data/Profiles/" + profile);
	dir.setPath("Data/Profiles/" + profile);
	dir.mkdir("Logs");
	dir.mkdir("Database");
}

void HBot::InitializeInterface()
{
	// Setup Interface

	m_InterfaceInitialized = true;

	m_HBotInterface = new QTabWidget(Ui_HBotClass::centralWidget);

	// Setup HBot Tab

	m_TabHBot = new QWidget();

	m_HBotInterface->addTab(m_TabHBot, QString::null);
	m_HBotInterface->setTabText(m_HBotInterface->indexOf(m_TabHBot), "HBot");

	m_HBotVerticalLayoutMain = new QVBoxLayout(m_TabHBot);
	m_HBotVerticalLayoutMain->setSpacing(6);
	m_HBotVerticalLayoutMain->setContentsMargins(11, 11, 11, 11);

	m_HBotGroupBox = new QGroupBox(m_TabHBot);
	m_HBotGroupBox->setTitle("Main Output Log");

	m_HBotVerticalLayout = new QVBoxLayout(m_HBotGroupBox);
	m_HBotVerticalLayout->setSpacing(6);
	m_HBotVerticalLayout->setContentsMargins(11, 11, 11, 11);

	m_OutputBrowser = new QTextBrowser(m_HBotGroupBox);
	m_PrintMutex = new QMutex(QMutex::Recursive);

	// DO NOT CALL PRINTCONSOLE UNTIL THIS POINT

	PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Initializing GUI interface.");

	m_HBotVerticalLayout->addWidget(m_OutputBrowser);
	m_HBotVerticalLayoutMain->addWidget(m_HBotGroupBox);

	// Setup Main Battle.net Tab

	m_TabBattlenet = new QWidget();
	
	m_HBotInterface->addTab(m_TabBattlenet, QString::null);
	m_HBotInterface->setTabText(m_HBotInterface->indexOf(m_TabBattlenet), "Battle.net");

	m_TabVerticalLayout = new QVBoxLayout(m_TabBattlenet);
	m_TabVerticalLayout->setSpacing(6);
	m_TabVerticalLayout->setContentsMargins(11, 11, 11, 11);

	m_BNETTabWidget = new QTabWidget(m_TabBattlenet);

	m_BNETTabs.push_back(new QWidget());

	m_BNETTabWidget->addTab(m_BNETTabs[0], QString::null);
	m_BNETTabWidget->setTabText(m_BNETTabWidget->indexOf(m_BNETTabs[0]), "Main");

	m_BNETVerticalLayoutMain.push_back(new QVBoxLayout(m_BNETTabs[0]));
	m_BNETVerticalLayoutMain[0]->setSpacing(6);
	m_BNETVerticalLayoutMain[0]->setContentsMargins(11, 11, 11, 11);

	m_BNETGroupBox.push_back(new QGroupBox(m_BNETTabs[0]));
	m_BNETGroupBox[0]->setTitle("Battle.net Main Ouput Log");

	m_BNETVerticalLayout.push_back(new QVBoxLayout(m_BNETGroupBox[0]));
	m_BNETVerticalLayout[0]->setSpacing(6);
	m_BNETVerticalLayout[0]->setContentsMargins(11, 11, 11, 11);

	m_BNETOutputBrowser = new QTextBrowser(m_BNETGroupBox[0]);

	m_BNETVerticalLayout[0]->addWidget(m_BNETOutputBrowser);
	m_BNETVerticalLayoutMain[0]->addWidget(m_BNETGroupBox[0]);

	m_TabVerticalLayout->addWidget(m_BNETTabWidget);

	// Setup Database Tab
	
	m_TabDatabase = new QWidget();

	m_HBotInterface->addTab(m_TabDatabase, QString::null);
	m_HBotInterface->setTabText(m_HBotInterface->indexOf(m_TabDatabase), "Database");

	m_TabVerticalLayoutDatabase = new QVBoxLayout(m_TabDatabase);
	m_TabVerticalLayoutDatabase->setSpacing(6);
	m_TabVerticalLayoutDatabase->setContentsMargins(11, 11, 11, 11);

	m_DatabaseComboBox = new QComboBox();
	m_DatabaseComboBox->setEnabled(false);

	m_DatabaseConnectButton = new QPushButton("Open Database");
	m_DatabaseConnectButton->setToolTip("Open database to view data or make changes. You can not open the database while the bot is running.");
	m_DatabaseConnectButton->setEnabled(false);
	m_DatabaseDisconnectButton = new QPushButton("Close Database");
	m_DatabaseDisconnectButton->setEnabled(false);
	m_DatabaseDisconnectButton->setToolTip("Close the database if it is currently open. This does not save modified data,\n you must use Submit to save modified data.");
	m_DatabaseSubmitButton = new QPushButton("Submit");
	m_DatabaseSubmitButton->setEnabled(false);
	m_DatabaseSubmitButton->setToolTip("Save any modified data you have currently changed.");
	m_DatabaseInsertRowButton = new QPushButton("Insert Row");
	m_DatabaseInsertRowButton->setToolTip("Insert a row into the table.");
	m_DatabaseInsertRowButton->setEnabled(false);
	m_DatabaseDeleteRowButton = new QPushButton("Delete row");
	m_DatabaseDeleteRowButton->setToolTip("Delete the currently selected row.");
	m_DatabaseDeleteRowButton->setEnabled(false);

	m_DatabaseButtonBox = new QDialogButtonBox(Qt::Horizontal);
	m_DatabaseButtonBox->addButton(m_DatabaseConnectButton, QDialogButtonBox::ActionRole);
	m_DatabaseButtonBox->addButton(m_DatabaseDisconnectButton, QDialogButtonBox::ActionRole);
	m_DatabaseButtonBox->addButton(m_DatabaseSubmitButton, QDialogButtonBox::ActionRole);

	m_DatabaseButtonBox2 = new QDialogButtonBox(Qt::Horizontal);
	m_DatabaseButtonBox2->addButton(m_DatabaseInsertRowButton, QDialogButtonBox::ActionRole);
	m_DatabaseButtonBox2->addButton(m_DatabaseDeleteRowButton, QDialogButtonBox::ActionRole);

	m_DatabaseHorizontalLayout = new QHBoxLayout();
	m_DatabaseHorizontalLayout->addWidget(m_DatabaseComboBox);
	m_DatabaseHorizontalLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
	m_DatabaseHorizontalLayout->addWidget(m_DatabaseButtonBox2);
	m_DatabaseHorizontalLayout->addWidget(m_DatabaseButtonBox);

	m_DatabaseTableView = new QTableView();
	m_DatabaseTable = NULL;
	
	m_TabVerticalLayoutDatabase->addWidget(m_DatabaseTableView);
	m_TabVerticalLayoutDatabase->addLayout(m_DatabaseHorizontalLayout);

	connect(m_DatabaseConnectButton, SIGNAL(clicked()), this, SLOT(ActionOpenDatabase()));
	connect(m_DatabaseDisconnectButton, SIGNAL(clicked()), this, SLOT(ActionCloseDatabase()));
	connect(m_DatabaseSubmitButton, SIGNAL(clicked()), this, SLOT(ActionSubmitChangesDatabase()));
	connect(m_DatabaseInsertRowButton, SIGNAL(clicked()), this, SLOT(ActionInsertRowDatabase()));
	connect(m_DatabaseDeleteRowButton, SIGNAL(clicked()), this, SLOT(ActionDeleteRowDatabase()));
	
	// Add Interface to Main Layout

	verticalLayout->addWidget(m_HBotInterface);

	PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Successfully initialized GUI interface.");
}

void HBot::OpenProfile(const QString &profile)
{
	setWindowTitle(windowTitle().left(windowTitle().indexOf(":")) + ": " + profile);
	PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Opening profile [" + profile + "]. HBot v" HBOT_VERSION);

	m_CurrentProfile = profile;
	m_XMLProfile->Read();
	m_Bot = new CHBot(profile);

	// Add Table Names
	
	if (m_Bot->GetDatabaseType() == 0)
	{
		m_DatabaseComboBox->insertItems(0, QStringList() << "Bans" << "DotA Games" << "DotA Players" << "Games" << "Game Players" << "Scores" << "Users" << "W3MMD Players" << "W3MMD Vars" << "Config");
	}
	else if (m_Bot->GetDatabaseType() == 1)
	{
		m_DatabaseComboBox->insertItems(0, QStringList() << "Bans" << "DotA Games" << "DotA Players" << "Games" << "Game Players" << "Scores" << "Users" << "W3MMD Players" << "W3MMD Vars");
	}

	connect(m_DatabaseComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(ActionDatabaseComboBoxChanged(int)));

	// Add Battle.net Tabs

	QVector<int> battlenetServers = g_HBotClass.GetNumberBnet();

	for (int i = 0; i < battlenetServers.size(); ++i)
	{
		m_BNETTabs.push_back(new QWidget());

		m_BNETTabWidget->addTab(m_BNETTabs.back(), QString::null);
		m_BNETTabWidget->setTabText(m_BNETTabWidget->indexOf(m_BNETTabs.back()), tr("Battle.net-%1: %2").arg(battlenetServers[i] + 1).arg(g_HBotClass.GetBNet()[i]->GetServer()));
	}
	
	if (m_XMLProfile->GetProfileValue("0", m_CurrentProfile, TAG_PROFILE_PROFILE, TAG_PROFILE_PROFILE_RUNONOPEN) == "1")
	{
		if (!m_Bot->GetError())
		{
			actionStop_Bot->setEnabled(true);
		}
	}
	else
	{
		if (!m_Bot->GetError())
		{
			actionRun_Bot->setEnabled(true);
		}
	}

	if (m_Bot->GetError())
	{
		PrintConsole(PRINT_CONSOLE_GROUP_HBOT, "Error detected. Halting initialization of profile. Fix the error and reopen the profile.", QString::null, true);
	}

	actionClose_Current_Profile->setEnabled(true);
}

void HBot::PrintConsole(const QString &group, const QString &message, const QString &subGroup, bool error)
{
	// Handle different groups.
	// This is really just a way to color code them.

	m_PrintMutex->lock();
	
	QString appendThis = "<font size=\"4\" color=\"";

	if (error)
	{
		appendThis += "red";
	}
	else
	{
		if (group == PRINT_CONSOLE_GROUP_HBOT)
		{
			appendThis += PRINT_CONSOLE_GROUP_HBOT_COLOR;
		}
		else if (group == PRINT_CONSOLE_GROUP_BNET)
		{
			appendThis += PRINT_CONSOLE_GROUP_BNET_COLOR;
		}
		else if (group == PRINT_CONSOLE_GROUP_CONFIG)
		{
			appendThis += PRINT_CONSOLE_GROUP_CONFIG_COLOR;
		}
		else if (group == PRINT_CONSOLE_GROUP_DATABASE)
		{
			appendThis += PRINT_CONSOLE_GROUP_DATABASE_COLOR;
		}
		else if (group == PRINT_CONSOLE_GROUP_LOG)
		{
			appendThis += PRINT_CONSOLE_GROUP_LOG_COLOR;
		}
		else if (group == PRINT_CONSOLE_GROUP_SIGNAL)
		{
			appendThis += PRINT_CONSOLE_GROUP_SIGNAL_COLOR;
		}
	}

	appendThis += "\"><b>[" + group + (subGroup.isEmpty() ? QString::null : ": " + subGroup) + "]</b></font><font size=\"4\"> " + message + "</font>";
	m_OutputBrowser->append(appendThis);

	
	if (group == PRINT_CONSOLE_GROUP_BNET)
	{
		m_BNETOutputBrowser->append(appendThis);
	}

	// Logging

	if (g_HBotClass.GetPtr())
	{
		if (g_HBotClass.GetLogMethod() != LOGGING_DISABLED)
		{
			if (g_HBotClass.GetLogMethod() == LOGGING_METHOD_1)
			{
			#ifdef _DEBUG
				assert(g_HBotClass.GetLog() != NULL);
			#else
				if (g_HBotClass.GetLog() != NULL)
				{
			#endif
					if (!g_HBotClass.GetLogDevice()->error())
					{
						QDateTime dateTimeString = QDateTime::currentDateTime();

						*(g_HBotClass.GetLog()) << "[" << dateTimeString.toString() << "] " << "[" << group << (subGroup.isEmpty() ? QString::null : ": " + subGroup) << "] " << message << endl;
						g_HBotClass.GetLog()->flush();
					}
					else
					{
						g_HBotClass.SetLogMethod(LOGGING_DISABLED);
						PrintConsole(PRINT_CONSOLE_GROUP_LOG, "Error: Unable to write to log file [" + g_HBotClass.GetLogFile() + "] - " + g_HBotClass.GetLogDevice()->errorString(), QString::null, true);
					}
			#ifdef NDEBUG
				}
				else
				{
					g_HBotClass.SetLogMethod(LOGGING_DISABLED);
					PrintConsole(PRINT_CONSOLE_GROUP_LOG, "Error: Unable to write to log file [" + g_HBotClass.GetLogFile() + "] - Logging disabled.", QString::null, true);
				}
			#endif // NDEBUG
			}
			else if (g_HBotClass.GetLogMethod() == LOGGING_METHOD_2)
			{
				QFile file(g_HBotClass.GetLogFile());
				
				if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
				{
					g_HBotClass.SetLogMethod(LOGGING_DISABLED);
					PrintConsole(PRINT_CONSOLE_GROUP_LOG, "Error: Failed to open log file [" + g_HBotClass.GetLogFile() + "] - " + file.errorString() + " Logging disabled.", QString::null, true);
				}
				else
				{
					QTextStream log(&file);

					QDateTime dateTimeString = QDateTime::currentDateTime();

					log << "[" << dateTimeString.toString() << "] " << "[" << group << "] " << message << endl;

					if (file.error())
					{
						g_HBotClass.SetLogMethod(LOGGING_DISABLED);
						PrintConsole(PRINT_CONSOLE_GROUP_LOG, "Error: Unable to write to log file [" + g_HBotClass.GetLogFile() + "] - " + file.errorString() + " Logging disabled.", QString::null, true);
					}

					file.close();
				}
			}
		}
	}

	m_PrintMutex->unlock();
}

bool HBot::CloseProfile()
{
	// Change Window Title

	setWindowTitle(windowTitle().left(windowTitle().indexOf(":")));

	// Close database if it is open.
	
	if (m_DatabaseTable)
	{
		if (!ActionCloseDatabase(false))
		{
			return false;
		}
	}

	// Important to do this part first!

	if (g_HBotClass.GetDatabaseType() == 1)
	{
		PrintConsole(PRINT_CONSOLE_GROUP_DATABASE, "Closing MySQL database connection to server [" + g_HBotClass.GetDatabase()->GetDatabase()->hostName() + "]", "MySQL");
		g_HBotClass.GetDatabase()->SetThreadGoal(1);
		g_HBotClass.GetDatabase()->start();
	}

	// Remove table names

	disconnect(m_DatabaseComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(ActionDatabaseComboBoxChanged(int)));
	m_DatabaseComboBox->clear();

	// Remove all Battle.net tabs besides Main

	for (int i = 1; i < m_BNETTabs.count(); ++i)
	{
		m_BNETTabs[i]->deleteLater();
	}

	m_BNETTabs.remove(1, m_BNETTabs.count() - 1);
	
	for (int i = (m_BNETTabWidget->count() - 1); i > 0; --i)
	{
		m_BNETTabWidget->removeTab(i);
	}

	// Delete bot class

	delete m_Bot;
	
	// DO NOT PRINT AFTER THIS POINT

	m_Bot = NULL;

	actionClose_Current_Profile->setEnabled(false);
	actionRun_Bot->setEnabled(false);
	actionStop_Bot->setEnabled(false);
	m_DatabaseConnectButton->setEnabled(false);
	m_DatabaseDisconnectButton->setEnabled(false);
	m_DatabaseSubmitButton->setEnabled(false);
	m_DatabaseComboBox->setEnabled(false);

	// Clear HBot output log
	
	m_OutputBrowser->clear();

	// Clear BNET output log

	m_BNETOutputBrowser->clear();
	m_CurrentProfile.clear();

	return true;
}

bool HBot::ContainsInvalidCharacters(const QString &filename)
{
	if (filename.contains('\\') || filename.contains('/') || filename.contains(':') || filename.contains('*') || filename.contains('?') || filename.contains('\"') || filename.contains('<') || filename.contains('>') || filename.contains('|'))
	{
		return true;
	}

	return false;
}

bool HBot::DeleteDirectory(const QString &profileDir)
{
	bool res = true;
	QDir dir(profileDir);
	
	if (dir.exists(profileDir))
	{
		Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
		{
			if (info.isDir())
			{
				res = DeleteDirectory(info.absoluteFilePath());
			}
			else
			{
				res = QFile::remove(info.absoluteFilePath());
			}

			if (!res)
			{
				return res;
			}
		}
		
		res = dir.rmdir(profileDir);
	}

	return res;
}
